package com.demo.sso.sdk.config;

import com.demo.sso.sdk.interceptor.SsoLoginInterceptor;
import com.demo.sso.sdk.service.SsoClientService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * SSO SDK自动配置类
 * 
 * @author SpringCloud团队
 * @version 1.0.0
 * @since 2025-01-01
 */
@Configuration
@EnableConfigurationProperties({SsoSdkProperties.class})
@ComponentScan(basePackages = "com.demo.sso.sdk")
@ConditionalOnProperty(prefix = "sso.sdk", name = "enabled", havingValue = "true", matchIfMissing = true)
//@EnableScheduling
public class SsoSdkAutoConfiguration implements WebMvcConfigurer {

    private static final Logger logger = LoggerFactory.getLogger(SsoSdkAutoConfiguration.class);

    private final SsoSdkProperties properties;

    public SsoSdkAutoConfiguration(SsoSdkProperties properties) {
        this.properties = properties;
        
        logger.info("SSO SDK auto configuration initialized with properties: {}", properties);
        
        // 验证配置
        if (!properties.isValid()) {
            logger.warn("SSO SDK configuration is invalid. Please check your configuration.");
        }
    }

    /**
     * 创建SSO客户端服务Bean
     *
     * @param properties SSO配置属性
     * @return SSO客户端服务实例
     */
    @Bean
    public SsoClientService ssoClientService(SsoSdkProperties properties) {
        return new SsoClientService(properties);
    }

    /**
     * 注册SSO登录拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        if (properties.getEnabled() && properties.isValid()) {
            registry.addInterceptor(new SsoLoginInterceptor(ssoClientService(properties), properties))
                    .addPathPatterns("/**")
                    .excludePathPatterns(
                            properties.getLoginPath(),
                            properties.getLogoutPath(),
                            properties.getCallbackPath(),
                            "/static/**",
                            "/css/**",
                            "/js/**",
                            "/images/**",
                            "/img/**",
                            "/favicon.ico",
                            "/api/public/**",
                            "/error"
                    );
            logger.info("SSO login interceptor registered successfully");
        } else {
            logger.warn("SSO login interceptor not registered due to invalid configuration");
        }
    }

    /**
     * 创建SSO登录拦截器Bean
     * 
     * @param ssoClientService SSO客户端服务
     * @param properties SSO配置属性
     * @return SSO登录拦截器实例
     */
    @Bean
    public SsoLoginInterceptor ssoLoginInterceptor(SsoClientService ssoClientService, SsoSdkProperties properties) {
        return new SsoLoginInterceptor(ssoClientService, properties);
    }

    /**
     * 定期清理过期缓存
     * 每5分钟执行一次
     */
    @Scheduled(fixedRate = 300000) // 5分钟
    public void cleanExpiredCache(SsoClientService ssoClientService) {
        if (properties.getEnabled() && properties.getUserInfoCacheTimeout() > 0) {
            try {
                ssoClientService.cleanExpiredCache();
                logger.debug("Expired SSO cache cleaned successfully");
            } catch (Exception e) {
                logger.error("Failed to clean expired SSO cache", e);
            }
        }
    }

    /**
     * 配置验证Bean
     * 在应用启动时验证SSO配置
     */
    @Bean
    public SsoConfigurationValidator ssoConfigurationValidator() {
        return new SsoConfigurationValidator(properties);
    }

    /**
     * SSO配置验证器
     */
    public static class SsoConfigurationValidator {
        
        private static final Logger logger = LoggerFactory.getLogger(SsoConfigurationValidator.class);
        
        private final SsoSdkProperties properties;

        public SsoConfigurationValidator(SsoSdkProperties properties) {
            this.properties = properties;
            validateConfiguration();
        }

        private void validateConfiguration() {
            if (!properties.getEnabled()) {
                logger.info("SSO SDK is disabled");
                return;
            }

            logger.info("Validating SSO SDK configuration...");

            boolean isValid = true;
            StringBuilder errorMessages = new StringBuilder();

            if (properties.getServerUrl() == null || properties.getServerUrl().trim().isEmpty()) {
                isValid = false;
                errorMessages.append("SSO server URL is required; ");
            }

            if (properties.getClientId() == null || properties.getClientId().trim().isEmpty()) {
                isValid = false;
                errorMessages.append("SSO client ID is required; ");
            }

            if (properties.getClientSecret() == null || properties.getClientSecret().trim().isEmpty()) {
                isValid = false;
                errorMessages.append("SSO client secret is required; ");
            }

            if (properties.getRedirectUri() == null || properties.getRedirectUri().trim().isEmpty()) {
                isValid = false;
                errorMessages.append("SSO redirect URI is required; ");
            }

            if (!isValid) {
                String errorMessage = "SSO SDK configuration validation failed: " + errorMessages.toString();
                logger.error(errorMessage);
                throw new IllegalStateException(errorMessage);
            }

            logger.info("SSO SDK configuration validation passed");
        }
    }
}